home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / tex / pastex14-beta-6 / lsfont / lsfont.c next >
C/C++ Source or Header  |  1994-03-16  |  11KB  |  530 lines

  1.  
  2. /*
  3.  *  lsfont.c
  4.  *
  5.  *  Author: Georg Heßmann (Hessmann@Informatik.Uni-Hamburg.De)
  6.  *
  7.  *  Copyright: source/program is FD (freely distributable) © Georg Heßmann 1993
  8.  *             It's part of the PasTeX distribution.
  9.  *
  10.  *  Why do I need this program?
  11.  *
  12.  *    If you work with PasTeX and you don't have enough disk space,
  13.  *    you might want only the pk-files you really need on the disk.
  14.  *
  15.  *    Here helps this program, together with the MARK option of
  16.  *    ShowDVI and DVIprint. Start ShowDVI and DVIprint always
  17.  *    with the MARK option (put it into ENVARC:SHOWDVI and 
  18.  *    ENVARC:DVIPRINT) and the drivers will mark every font they
  19.  *    used with an use-count and a date-stamp.
  20.  *
  21.  *    After some time, if you want get rid of old, seldom used fonts,
  22.  *    start "lsfont TeX:pk TO ram:fontlist" and look into the generated
  23.  *    list. The first number is the use count. So often is the font
  24.  *    used from a driver (started with MARK).
  25.  *
  26.  *    If you want delete some fonts of the list, do 
  27.  *    "lsfont TeX:pk TO ram:fontlist DELETE" and edit the file (delete all
  28.  *    fonts out of the file which you *don't* want delete from your
  29.  *    harddisk). After that, you can "execute ram:fontlist" delete the
  30.  *    old fonts.
  31.  *
  32.  *    Other idea to use the list:
  33.  *    Do copy the fonts first on some floppy-disks and delete them after
  34.  *    that from the hard-disk. Now, if you put your backup floppies into
  35.  *    TeX:config/FontVols, the drivers will find them on your floppies.
  36.  *    
  37.  *
  38.  *  Version history:
  39.  *
  40.  *  0.1  18.Jul.93  First try.
  41.  *  1.0  16.Mar.94  Release it with PasTeX 1.4 -- BETA 1 --
  42.  *
  43.  */
  44.  
  45.  
  46. #define VERSION "1.0"
  47.  
  48. static const char version[] = "$VER: lsfont " VERSION " (16.03.94)";
  49.  
  50.  
  51. /*
  52.  * Program is 2.04 or higher only!!
  53.  *
  54.  */
  55.  
  56. long __oslibversion = 37;
  57.  
  58.  
  59.  
  60. #include "lsfont.h"
  61.  
  62.  
  63. /*
  64.  * Template for ReadArgs()
  65.  */
  66.  
  67. #define TEMPLATE    "NAME/M,TO/K,DELETE/S"
  68.  
  69.  
  70. /*
  71.  * Used Libraries
  72.  */
  73.  
  74. extern struct Library * DOSBase;
  75. extern struct Library * UtilityBase;
  76.  
  77.  
  78. /*
  79.  * File list structure
  80.  *
  81.  */
  82.  
  83. struct FLst {
  84.   long               flst_Used;
  85.   BPTR               flst_Lock;
  86.   struct DateStamp   flst_DateStamp;
  87.   struct FLst      * flst_Next;
  88. };
  89.  
  90.  
  91. /*
  92.  * Global Vars
  93.  *
  94.  */
  95.  
  96. static char          NameBuf[1024];
  97. static struct FLst * FileLstRoot = NULL;
  98. static int           SizeFileLst = 0;
  99. static FILE        * OutputFile;
  100. static int           OutDelete;
  101.  
  102.  
  103.  
  104. /*
  105.  * Disable SAS/C CTRL-C functions
  106.  *
  107.  */
  108.  
  109. int CXBRK(void) { return(0); }
  110. int _CXBRK(void) { return(0); }
  111. void chkabort(void) { return; }
  112.  
  113.  
  114.  
  115. /*
  116.  * Usefull macro to check Ctrl-C
  117.  */
  118.  
  119. #define IsCtrlC        (SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
  120.  
  121.  
  122.  
  123.  
  124. /*
  125.  * Prototypes of the help functions
  126.  */
  127.  
  128. static int  DoArg        (char * name);
  129. static int  DoDir        (BPTR lck);
  130. static int  DoFile       (BPTR lck, struct FileInfoBlock * fib);
  131. static int  CompareFiles (const void * A, const void * B);
  132. static int  SortFileLst  (void);
  133. static void FreeFileLst  (void);
  134. static int  CheckCtrlC   (int);
  135.  
  136.  
  137.  
  138.  
  139. /*
  140.  * Main function. 
  141.  */
  142.  
  143. int main(int argc, char * argv[])
  144. {
  145.   long rc = RETURN_OK;
  146.   long options[3];
  147.   struct RDArgs * args;
  148.  
  149.   memset(options, 0, sizeof(options));
  150.  
  151.   args = ReadArgs(TEMPLATE, options, NULL);
  152.   if (args) {
  153.     char ** dirs = (char **)options[0];
  154.     char * NoArg[2];
  155.     
  156.     OutDelete = options[2];
  157.     
  158.     if (options[1]) {
  159.       OutputFile = fopen((char *)options[1], "w");
  160.       if (!OutputFile) {
  161.         PrintFault(IoErr(), (char *)options[1]);
  162.         rc = RETURN_ERROR;
  163.       }
  164.     }
  165.     else {
  166.       OutputFile = stdout;
  167.     }
  168.  
  169.     if (rc == RETURN_OK && !dirs) {
  170.       // wenn keine Argumente angegeben, dann Name des akt. Dirs. verwenden
  171.       char * namebuf = malloc(500);
  172.       if (!namebuf) {
  173.         PrintFault(ERROR_NO_FREE_STORE, NULL);
  174.         rc = RETURN_ERROR;
  175.       }
  176.       else {
  177.         BPTR lock = Lock("", ACCESS_READ);
  178.         if (!lock) {
  179.           PrintFault(IoErr(), "\"\"");
  180.           rc = RETURN_ERROR;
  181.         }
  182.         else {
  183.           if (!NameFromLock(lock, namebuf, 499)) {
  184.             PrintFault(IoErr(), "\"\"");
  185.             rc = RETURN_ERROR;
  186.           }
  187.           else {
  188.             NoArg[0] = namebuf;        // Name des aktuellen Directories
  189.             NoArg[1] = NULL;
  190.             dirs = NoArg;
  191.           }
  192.           UnLock(lock);
  193.         }
  194.       }
  195.     }
  196.  
  197.     if (rc == RETURN_OK) {
  198.       char * PatBuf = NULL;
  199.       char * ptr;
  200.   
  201.       for (; rc == RETURN_OK && (ptr = *dirs); dirs++) {
  202.         int isWild;
  203.  
  204.         if (PatBuf == NULL) PatBuf = malloc(1024);
  205.         if (PatBuf == NULL) {
  206.           PrintFault(ERROR_NO_FREE_STORE, NULL);
  207.           rc = RETURN_ERROR;
  208.           break;
  209.         }
  210.         isWild = ParsePatternNoCase(ptr, PatBuf, 1023);
  211.         
  212.         if (isWild < 0) {
  213.           PrintFault(IoErr(), NULL);
  214.           rc = RETURN_ERROR;
  215.           break;
  216.         }
  217.         else {
  218.           if (isWild == 0) {
  219.             // Kein Pattern
  220.             rc = DoArg(ptr);
  221.             if (rc != RETURN_OK) break;
  222.           }
  223.           else {
  224.             // Pattern
  225.             char __aligned buf[sizeof(struct AnchorPath)+200];
  226.             struct AnchorPath * ap = (struct AnchorPath *)buf;
  227.  
  228.             memset(ap, 0, sizeof(struct AnchorPath));
  229.             ap->ap_Strlen = 200;
  230.  
  231.             if (MatchFirst(PatBuf, ap) == 0) {
  232.               rc = DoArg(ap->ap_Buf);
  233.               while (rc == RETURN_OK && MatchNext(ap) == 0) {
  234.                 rc = DoArg(ap->ap_Buf);
  235.                 if (rc != RETURN_OK) MatchEnd(ap);
  236.               }
  237.               if (rc != RETURN_OK) break;
  238.             }
  239.             else {
  240.               PrintFault(IoErr(), NULL);
  241.               rc = RETURN_FAIL;
  242.             }
  243.           }
  244.         }
  245.  
  246.       }
  247.       
  248.       if (rc == RETURN_OK) {
  249.         rc = SortFileLst();
  250.       }
  251.  
  252.       FreeFileLst();
  253.       FreeArgs(args);
  254.     }
  255.   }
  256.   else {
  257.     PrintFault(IoErr(), NULL);
  258.     rc = RETURN_ERROR;
  259.   }
  260.   
  261.   return rc;
  262. }
  263.  
  264.  
  265.  
  266. /*
  267.  * DoArg()
  268.  *
  269.  * Nimm einen Namen (Dir oder File) und teste ihn.
  270.  *
  271.  */
  272.  
  273. static int DoArg(char * name)
  274. {
  275.   long ret;
  276.   __aligned struct FileInfoBlock fib;
  277.   BPTR lck;
  278.   
  279.   lck = Lock(name, ACCESS_READ);
  280.   if (lck) {
  281.     if (Examine(lck, &fib)) {
  282.       if (fib.fib_DirEntryType > 0) {
  283.         ret = DoDir(lck);
  284.       }
  285.       else {
  286.         ret = DoFile(lck, &fib);
  287.       }
  288.     }
  289.     else {
  290.       PrintFault(IoErr(), name);
  291.       ret = RETURN_ERROR;
  292.     }
  293.     UnLock(lck);
  294.   }
  295.   else {
  296.     PrintFault(IoErr(), name);
  297.     ret = RETURN_ERROR;
  298.   }
  299.   
  300.   return ret;    
  301. }
  302.  
  303.  
  304. /*
  305.  * DoDir()
  306.  * 
  307.  * Durchsuche ein ganzes Directory.
  308.  *
  309.  */
  310.  
  311. static int DoDir(BPTR lck)
  312. {
  313.   int ret = RETURN_OK;
  314.   BPTR newlck = DupLock(lck);
  315.   int err;
  316.   __aligned struct FileInfoBlock newfib;
  317.  
  318.   if (newlck) {
  319.     if (Examine(newlck, &newfib)) {
  320.       while (ret == RETURN_OK && ExNext(newlck, &newfib)) {
  321.         BPTR olddir = CurrentDir(newlck);
  322.         BPTR new = Lock(newfib.fib_FileName, ACCESS_READ);
  323.         if (new) {
  324.           if (newfib.fib_DirEntryType > 0) {
  325.             ret = DoDir(new);
  326.           }
  327.           else {
  328.             ret = DoFile(new, &newfib);
  329.           }
  330.           UnLock(new);
  331.         }
  332.         else {
  333.           PrintFault(IoErr(), newfib.fib_FileName);
  334.           ret = RETURN_ERROR;
  335.         }
  336.         CurrentDir(olddir);
  337.         ret = CheckCtrlC(ret);
  338.       }
  339.  
  340.       if (ret == RETURN_OK) {
  341.         err = IoErr();
  342.         if (err != ERROR_NO_MORE_ENTRIES) {
  343.           PrintFault(err, NULL);
  344.           ret = RETURN_ERROR;
  345.         }
  346.       }
  347.     }
  348.     UnLock(newlck);
  349.   }
  350.  
  351.  
  352.   return ret;
  353. }
  354.  
  355.  
  356. /*
  357.  * DoFile()
  358.  * 
  359.  * Ein File abtesten.
  360.  *
  361.  */
  362.  
  363. static int DoFile(BPTR lck, struct FileInfoBlock * fib)
  364. {
  365.   int ret = RETURN_OK;
  366.   long num = 0;
  367.   struct FLst * flst;
  368.   
  369.   flst = malloc(sizeof(struct FLst));
  370.   if (!flst) {
  371.     PrintFault(ERROR_NO_FREE_STORE, NULL);
  372.     return RETURN_ERROR;
  373.   }
  374.   
  375.   if (!strncmp(fib->fib_Comment, "FontUsed: ", 10)) {
  376.     if (sscanf(fib->fib_Comment+10, "%d (%d %d %d)", 
  377.         &num, &flst->flst_DateStamp.ds_Days, &flst->flst_DateStamp.ds_Minute, 
  378.     &flst->flst_DateStamp.ds_Tick) != 4) {
  379.       num = 0;
  380.     }
  381.   }
  382.   
  383.   if (num == 0) {
  384.     // nehme als Zeit das Datum des Files
  385.     flst->flst_DateStamp = fib->fib_Date;
  386.   }
  387.   
  388.   flst->flst_Used = num;
  389.   flst->flst_Lock = DupLock(lck);
  390.   
  391.   if (!flst->flst_Lock) {
  392.     PrintFault(IoErr(), NULL);
  393.     return RETURN_ERROR;
  394.   }
  395.   
  396.   // in die Liste einhaengen
  397.   flst->flst_Next = FileLstRoot;
  398.   FileLstRoot = flst;
  399.   SizeFileLst++;
  400.  
  401.   return ret;
  402. }
  403.  
  404.  
  405.  
  406. /*
  407.  * CompareFiles()
  408.  *
  409.  * Compare to FLst structures. Will be called from qsort()
  410.  *
  411.  */
  412.  
  413. static int CompareFiles(const void * A, const void * B)
  414. {
  415.   struct FLst * a = *(struct FLst **)A;
  416.   struct FLst * b = *(struct FLst **)B;
  417.   
  418.   if (a->flst_Used == b->flst_Used) {
  419.     return CompareDates(&b->flst_DateStamp, &a->flst_DateStamp);
  420.   }
  421.   else {
  422.     return a->flst_Used - b->flst_Used;
  423.   }
  424. }
  425.  
  426.  
  427.  
  428.  
  429. /*
  430.  * SortFileLst()
  431.  *
  432.  * Soriere die aufgebaute Liste von Files und gib sie aus
  433.  *
  434.  */
  435.  
  436. static int SortFileLst(void)
  437. {
  438.   int ret = RETURN_OK;
  439.   __aligned struct FileInfoBlock fib;
  440.   struct FLst *  flst;
  441.   struct FLst ** SortArr;
  442.   int i;
  443.   
  444.   SortArr = malloc(SizeFileLst * sizeof(struct FLst *));
  445.   if (!SortArr) {
  446.     PrintFault(ERROR_NO_FREE_STORE, NULL);
  447.     return RETURN_ERROR;
  448.   }
  449.  
  450.   for (flst = FileLstRoot, i=0; flst; flst = flst->flst_Next, i++) {
  451.     SortArr[i] = flst;
  452.   }
  453.  
  454.   ret = CheckCtrlC(ret);
  455.   
  456.   /*
  457.    * Sortiere SortArr:
  458.    * Nach unten kommen die haeufig benuzten, bzw. vor kurem benutzten Files.
  459.    *
  460.    */
  461.  
  462.   if (ret == RETURN_OK) {
  463.     qsort(SortArr, SizeFileLst, sizeof(struct FLst *), CompareFiles);
  464.   }
  465.   
  466.   for (i=0; ret == RETURN_OK && i<SizeFileLst; i++) {
  467.     flst = SortArr[i];
  468.  
  469.     if (Examine(flst->flst_Lock, &fib)) {
  470.       if (NameFromLock(flst->flst_Lock, NameBuf, sizeof(NameBuf)-1)) {
  471.         if (OutDelete) {
  472.           fprintf(OutputFile, "delete %s FORCE\n", NameBuf);          
  473.         }
  474.         else {
  475.           fprintf(OutputFile, "%d\t%s\n", flst->flst_Used, NameBuf);          
  476.         }
  477.       }
  478.       else {
  479.         PrintFault(ERROR_BUFFER_OVERFLOW, NULL);
  480.         ret = RETURN_ERROR;
  481.       }
  482.     }
  483.     else {
  484.       PrintFault(IoErr(), NULL);
  485.       ret = RETURN_ERROR;
  486.     }
  487.     
  488.     ret = CheckCtrlC(ret);
  489.   }
  490.   
  491.   free(SortArr);
  492.   
  493.   return ret;
  494. }
  495.  
  496.  
  497.  
  498. /*
  499.  * FreeFileLst()
  500.  *
  501.  * Free all Lock's in the list.
  502.  *
  503.  */
  504.  
  505. static void FreeFileLst(void)
  506. {
  507.   struct FLst * flst;
  508.   
  509.   for (flst = FileLstRoot; flst; flst = flst->flst_Next) {
  510.     UnLock(flst->flst_Lock);
  511.   }
  512. }
  513.  
  514.  
  515.  
  516. /*
  517.  * Test for CTRL-C and return ERROR_WARN
  518.  *
  519.  */
  520.  
  521. static int CheckCtrlC(int ret)
  522. {
  523.   if (ret == RETURN_OK && IsCtrlC) {
  524.     PrintFault(ERROR_BREAK, NULL);
  525.     ret = RETURN_WARN;
  526.   }
  527.   
  528.   return ret;
  529. }
  530.